#include"mystdio.h"

my_file *myfopen(const char *path, const char *mode)
{
    int flag = 0;
    //解析flag成open的标志位
    if(strcmp(mode,"w")==0)
    {
        flag |= O_CREAT | O_WRONLY | O_TRUNC;
      //printf("%s\n",mode);
    }
    else if (strcmp(mode,"r")==0)
    {
        flag |= O_RDONLY;
    }
    else if (strcmp(mode,"a")==0)
    {        
        flag |= O_CREAT | O_WRONLY | O_APPEND;
    }
    else
    {
        perror("mode");
        exit(1);
    }
    
    //调系统调用打开文件
    mode_t m = 0666;
    int fd = 0;
    if(flag & O_CREAT) 
        fd = open(path,flag,m);
    else
        fd = open(path,flag);

    if(fd < 0) 
        return NULL;
    
    my_file *fp = (my_file*)malloc(sizeof(my_file));
    if(fp == NULL)
    {
        close(fd);
        perror("malloc");
        return NULL;
    }
    
    //初始化my_file结构体
    fp->fd = fd;
    fp->flags = BUF_LINE;
    fp->current = 0;
    memset(fp->outputbuffer,'\0',sizeof(fp->outputbuffer));
    return fp;
}


size_t myfwrite(const void *ptr, size_t size, size_t nmemb,my_file *stream)
{
    assert(stream);
    
    if(stream->current == NUM) 
        myfflush(stream);

   //size_t rest_size = NUM - stream->current;
   //size_t writend = 0;//最后实际写入的数据字节数
   //size_t usrsize = nmemb*size; 
   ////如果缓冲区足够用户写入
   //if(rest_size >= nmemb)
   //{
   //    memcpy(stream->outputbuffer+stream->current, ptr,usrsize);
   //    stream->current += usrsize;    //这里不能用+=nememb，会导致\n消失
   //    writend = usrsize;
   //}
   //else
   //{
   //    memcpy(stream->outputbuffer+stream->current, ptr,rest_size*size);
   //    stream->current += rest_size;
   //    writend = size*rest_size;
   //}
   
   size_t rest_size = NUM - stream->current;
   size_t writend = 0;//最后实际写入的数据字节数
   size_t usrsize = nmemb*size;
   //如果缓冲区足够用户写入
   if(rest_size >= nmemb)
   {
       memcpy(stream->outputbuffer+stream->current, ptr,usrsize);
       stream->current += usrsize;
       //stream->current += nmemb;
       writend = usrsize;
   }
   else
   {
       memcpy(stream->outputbuffer+stream->current, ptr,rest_size*size);
       stream->current += rest_size;
       writend = rest_size;
   }
    //判断什么时候需要刷新缓冲区
    //行缓冲
    //if(stream->flags == BUF_LINE)//注意不要用==，因为flags可以标志很多信息，每一个位都有其不同的作用,控制多种文件操纵方式
    if(stream->flags & BUF_LINE)
    {
       if(stream->outputbuffer[stream->current-1] == '\n')
           myfflush(stream);
    }
    else if(stream->flags & BUF_ALL)
    {
        if(stream->current == NUM)
            myfflush(stream);
    }
    else{}
    
    return writend; 
}


int myfflush(my_file *stream)
{
    assert(stream);
    write(stream->fd,stream->outputbuffer,stream->current);    
    stream->current = 0;
    return 0;
}


int myfclose(my_file *fp)
{
    assert(fp);
        
    myfflush(fp);

    close(fp->fd);

    //释放堆空间
    free(fp);
    fp=NULL;
    return 0;
}
